﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Remoting;

namespace FisheryPlatform.Search.Core.Resource
{
    public abstract class AbstractStreamResource : AbstractResource
    {
        // Methods
        public override void Dispose()
        {
            this.Dispose(true);
        }

        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                GC.SuppressFinalize(this);
            }
            if (this.Stream != null)
            {
                this.Stream.Close();
            }
        }

        ~AbstractStreamResource()
        {
            this.Dispose(false);
        }

        public override TextReader GetStreamReader()
        {
            return new StreamReader(new StreamHideCloseDelegate(this.Stream));
        }

        public override TextReader GetStreamReader(Encoding encoding)
        {
            return new StreamReader(new StreamHideCloseDelegate(this.Stream), encoding);
        }

        // Properties
        protected abstract Stream Stream { get; }

        // Nested Types
        public class StreamHideCloseDelegate : Stream, IDisposable
        {
            // Fields
            private readonly Stream inner;

            // Methods
            public StreamHideCloseDelegate(Stream inner)
            {
                this.inner = inner;
            }

            public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
            {
                return this.inner.BeginRead(buffer, offset, count, callback, state);
            }

            public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
            {
                return this.inner.BeginWrite(buffer, offset, count, callback, state);
            }

            public override void Close()
            {
            }

            public override ObjRef CreateObjRef(Type requestedType)
            {
                return this.inner.CreateObjRef(requestedType);
            }

            public override int EndRead(IAsyncResult asyncResult)
            {
                return this.inner.EndRead(asyncResult);
            }

            public override void EndWrite(IAsyncResult asyncResult)
            {
                this.inner.EndWrite(asyncResult);
            }

            public override void Flush()
            {
                this.inner.Flush();
            }

            public override object InitializeLifetimeService()
            {
                return this.inner.InitializeLifetimeService();
            }

            public override int Read(byte[] buffer, int offset, int count)
            {
                return this.inner.Read(buffer, offset, count);
            }

            public override int ReadByte()
            {
                return this.inner.ReadByte();
            }

            public override long Seek(long offset, SeekOrigin origin)
            {
                return this.inner.Seek(offset, origin);
            }

            public override void SetLength(long value)
            {
                this.inner.SetLength(value);
            }

            public override void Write(byte[] buffer, int offset, int count)
            {
                this.inner.Write(buffer, offset, count);
            }

            public override void WriteByte(byte value)
            {
                this.inner.WriteByte(value);
            }

            // Properties
            public override bool CanRead
            {
                get
                {
                    return this.inner.CanRead;
                }
            }

            public override bool CanSeek
            {
                get
                {
                    return this.inner.CanSeek;
                }
            }

            public override bool CanWrite
            {
                get
                {
                    return this.inner.CanWrite;
                }
            }

            public override long Length
            {
                get
                {
                    return this.inner.Length;
                }
            }

            public override long Position
            {
                get
                {
                    return this.inner.Position;
                }
                set
                {
                    this.inner.Position = value;
                }
            }
        }
    }


}
